package com.fhao.forum.services.impl;

import com.fhao.forum.common.AppResult;
import com.fhao.forum.common.ResultCode;
import com.fhao.forum.dao.UserMapper;
import com.fhao.forum.exception.ApplicationException;
import com.fhao.forum.model.User;
import com.fhao.forum.services.IUserService;
import com.fhao.forum.utils.MD5Util;
import com.fhao.forum.utils.StringUtil;
import com.fhao.forum.utils.UUIDUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Date;


/**
 * 用户接口具体实现
 */
@Slf4j
@Service
public class UserServiceImpl implements IUserService {
    
    @Autowired
    private UserMapper userMapper;
    
    @Override
    public void createNormalUser(User user) {
        //1. 非空校验
        if(user == null || StringUtil.isEmpty(user.getUsername())
                || StringUtil.isEmpty(user.getPassword())
                || StringUtil.isEmpty(user.getNickname())
                || StringUtil.isEmpty(user.getSalt())) {
            //打印日志
            log.warn("用户注册 "+ResultCode.FAILED_PARAMS_VALIDATE.toString());
            //抛 自定义的 Application异常
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED_PARAMS_VALIDATE));
        }
        //2. 根据用户名查询用户信息
        User existsUser = userMapper.selectByUserName(user.getUsername());
        if(existsUser != null) {
            //打印日志
            log.info(ResultCode.FAILED_USER_EXISTS.toString());
            //抛自定义异常 ApplicationException
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED_USER_EXISTS));
        }
        //3. 新增用户流程, 设置默认值
        user.setGender((byte) 2);
        user.setArticleCount(0);
        user.setIsAdmin((byte) 0);
        user.setState((byte) 0);
        user.setDeleteState((byte) 0);
        //设置当前日期
        Date date = new Date();
        user.setCreateTime(date);
        user.setUpdateTime(date);
        //写入数据库
        int row = userMapper.insertSelective(user);//动态插入新用户
        if(row < 1) {
            //打印日志
            log.info(ResultCode.FAILED_CREATE.toString());
            //抛异常
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED_CREATE));
        }
        //打印日志
        log.info("新增用户成功, username = " + user.getUsername() +" .");
    }

    @Override
    public User selectByUserName(String username) {
        if(StringUtil.isEmpty(username)) {
            //打印日志
            log.info(ResultCode.FAILED_PARAMS_VALIDATE.toString());
            //抛异常
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED_PARAMS_VALIDATE));
        }
        //返回查询结果
        return userMapper.selectByUserName(username);
    }

    @Override
    public User login(String username, String password) {
        log.info("{} 用户登录",username);
        //1. 参数校验
        if(StringUtil.isEmpty(username) || StringUtil.isEmpty(password)) {
            //打印日志
            log.warn(ResultCode.FAILED_PARAMS_VALIDATE.toString());
            //抛异常
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED_PARAMS_VALIDATE));
        }
        //2. 按用户名查询用户信息
        User user = userMapper.selectByUserName(username);
        //对查询信息进行非空校验
        if(user == null) {
            //打印日志
            log.warn(ResultCode.FAILED_LOGIN.toString()+", username = "+username);
            //抛异常
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED_LOGIN));
        }
        //3. 进行密码验证
        String encryptPassword = MD5Util.md5Salt(password,user.getSalt());
        if(!encryptPassword.equalsIgnoreCase(user.getPassword())) {
            //打印日志
            log.warn(ResultCode.FAILED_LOGIN.toString()+", username = "+username);
            //抛异常
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED_LOGIN));
        }
        //登录成功,打印日志
        log.info("登录成功,username = " + username);
        return user;
    }

    @Override
    public User selectById(Long id) {
        //参数校验
        if(id == null || id <= 0) {
            log.warn(ResultCode.FAILED_PARAMS_VALIDATE.toString());
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED_PARAMS_VALIDATE));
        }
        //从dao层数据库中获取用户信息
        User user = userMapper.selectByPrimaryKey(id);
        //此处参数校验交给controller进行,service层不进行参数校验.
        return user;
    }

    @Override
    public void addOneArticleCountById(Long id) {
        //参数校验
        if(id == null || id <= 0) {
            log.warn(ResultCode.FAILED_BOARD_ARTICLE_COUNT.toString());
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED_BOARD_ARTICLE_COUNT));
        }
        User user = userMapper.selectByPrimaryKey(id);
        if(user == null) {
            log.warn("UserServiceImpl 更新用户发帖数量" + ResultCode.ERROR_IS_NULL.toString());
            throw new ApplicationException(AppResult.failed(ResultCode.ERROR_IS_NULL));
        }
        //重新new一个user,设置要更新的参数
        User updateUser = new User();
        updateUser.setId(user.getId());
        updateUser.setArticleCount(user.getArticleCount()+1);
        //更新数据库
        int row = userMapper.updateByPrimaryKeySelective(updateUser);
        if(row != 1) {
            log.warn(ResultCode.FAILED.toString()+"受影响的行数不等于1 .");
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED));
        }
    }

    @Override
    public void subOneArticleCountById(Long id) {
        //参数校验
        if(id == null || id <= 0) {
            log.warn(ResultCode.FAILED_BOARD_ARTICLE_COUNT.toString());
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED_BOARD_ARTICLE_COUNT));
        }
        //拿到用户并判断用户是否存在
        User user = userMapper.selectByPrimaryKey(id);
        if(user == null) {
            log.warn("UserServiceImpl 更新用户发帖数量" + ResultCode.ERROR_IS_NULL.toString());
            throw new ApplicationException(AppResult.failed(ResultCode.ERROR_IS_NULL));
        }
        //重新new一个user,设置要更新的参数
        User updateUser = new User();
        updateUser.setId(user.getId());
        updateUser.setArticleCount(user.getArticleCount()-1);
        if(user.getArticleCount() < 0) {
            user.setArticleCount(0);
        }
        //更新数据库
        int row = userMapper.updateByPrimaryKeySelective(updateUser);
        if(row != 1) {
            log.warn(ResultCode.FAILED+"受影响的行数不等于1 .");
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED));
        }
    }

    @Override
    public void modifyInfo(User user) {
        //1. 参数校验
        if(user == null || user.getId() == null || user.getId() <= 0) {
            log.warn(ResultCode.FAILED_PARAMS_VALIDATE.toString());
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED_PARAMS_VALIDATE));
        }
        //2. 校验用户是否存在
        User existsUser = userMapper.selectByPrimaryKey(user.getId());
        if(existsUser == null) {
            log.warn(ResultCode.FAILED_USER_NOT_EXISTS.toString());
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED_USER_NOT_EXISTS));
        }
        //3. 定义一个标志位
        boolean checkAttr = false;//如果有一个参数不为空,就赋值为true
        //4. 创建一个专门用来更新的对象,防止用户传入的User对象设置了其他的属性,使用动态sql进行更新时覆盖了没有经过校验的字段
        User updataUser = new User();
        updataUser.setId(user.getId());
        //5. 对每一个参数进行校验并赋值
        //校验用户名
        if(!StringUtil.isEmpty(user.getUsername())
                && !user.getUsername().equals(existsUser.getUsername())) {
            //查询是否存在相同用户名的用户,用户名具有唯一性,不允许两个用户存在相同的用户名.
            User user1 = userMapper.selectByUserName(user.getUsername());
            if(user1 != null) {
                log.warn(ResultCode.FAILED_USER_EXISTS.toString());
                throw new ApplicationException(AppResult.failed(ResultCode.FAILED_USER_EXISTS));
            }
            updataUser.setUsername(user.getUsername());
            checkAttr = true;
        }
        //校验昵称
        if(!StringUtil.isEmpty(user.getNickname())
                && !user.getNickname().equals(existsUser.getNickname())) {
            updataUser.setNickname(user.getNickname());
            checkAttr = true;
        }
        //校验性别
        if(user.getGender() != null
                && user.getGender() != existsUser.getGender()) {
            updataUser.setGender(user.getGender());
            //合法性校验
            if(updataUser.getGender() > 2 || updataUser.getGender() < 0) {
                updataUser.setGender((byte) 2);
            }
            checkAttr = true;
        }
        //校验邮箱
        if(user.getEmail() != null
                && !user.getEmail().equals(existsUser.getEmail())) {
            updataUser.setEmail(user.getEmail());
            checkAttr = true;
        }
        //校验电话
        if(user.getPhoneNum() != null
                && !user.getPhoneNum().equals(existsUser.getPhoneNum())) {
            updataUser.setPhoneNum(user.getPhoneNum());
            checkAttr = true;
        }
        //校验个人简介
        if(user.getRemark() != null
                && !user.getRemark().equals(existsUser.getRemark())) {
            updataUser.setRemark(user.getRemark());
            checkAttr = true;
        }
        //没有一个需要改的.
        if(checkAttr == false) {
            log.warn(ResultCode.FAILED_PARAMS_VALIDATE.toString());
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED_PARAMS_VALIDATE));
        }
        int row = userMapper.updateByPrimaryKeySelective(updataUser);
        if(row != 1) {
            log.warn(ResultCode.ERROR_SERVICES.toString());
            throw new ApplicationException(AppResult.failed(ResultCode.ERROR_SERVICES));
        }
        log.info("userId = "+ user.getId() + " ,用户信息更新成功");
    }

    @Override
    public void modifyPassword(Long id, String oldPassword, String newPassword) {
        //参数校验
        if(id == null || id <= 0 || StringUtil.isEmpty(newPassword)
                || StringUtil.isEmpty(oldPassword)) {
            log.warn(ResultCode.FAILED_PARAMS_VALIDATE.toString());
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED_PARAMS_VALIDATE.toString()));
        }
        //拿到用户
        User user = userMapper.selectByPrimaryKey(id);
        if(user == null || user.getDeleteState() == 1) {
            log.warn(ResultCode.FAILED_USER_NOT_EXISTS.toString());
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED_USER_NOT_EXISTS.toString()));
        }
        //校验老密码是否正确
        String checkPassword = MD5Util.md5Salt(oldPassword, user.getSalt());
        if(!checkPassword.equalsIgnoreCase(user.getPassword())) {
            log.warn(ResultCode.FAILE_WRONG_PASSWORD.toString());
            throw new ApplicationException(AppResult.failed(ResultCode.FAILE_WRONG_PASSWORD));
        }
        //生成新的盐和密文
        String updateSalt = UUIDUtil.UUID_32();
        String updatePassword = MD5Util.md5Salt(newPassword,updateSalt);
        //封装对象
        User updateUser = new User();
        updateUser.setId(id); //用户id
        updateUser.setSalt(updateSalt); //新生成的盐
        updateUser.setPassword(updatePassword); // 新密码对应的密文
        Date date = new Date();
        updateUser.setUpdateTime(date); //更新时间
        //调用DAO
        int row = userMapper.updateByPrimaryKeySelective(updateUser);
        if(row != 1) {
            log.warn(ResultCode.ERROR_SERVICES.toString());
            throw new ApplicationException(AppResult.failed(ResultCode.ERROR_SERVICES));
        }

    }

}




















